﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security;
using System.Threading.Tasks;
using KC.Service.Core.DTO.Dict;
using KC.Framework.Base;
using KC.Framework.Tenant;
using KC.Service.Admin;
using KC.Service.Core;
using KC.DTO.Admin;
using KC.DTO.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace KC.WebApi.Admin.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TenantApiController : ControllerBase
    {
        private const string ServiceName = "KC.WebApi.Admin.Controllers.TenantController";

        private ITenantUserService TenantStore => ServiceProvider.GetService<ITenantUserService>();
        private readonly IServiceProvider ServiceProvider;
        private readonly ILogger Logger;
        public TenantApiController(IServiceProvider serviceProvider,
            ILogger<TenantApiController> logger)
        {
            Logger = logger;
            ServiceProvider = serviceProvider;
        }

        /// <summary>
        /// 租户名称是否存在
        /// </summary>
        /// <param name="tenantName">租户代码</param>
        /// <returns>租户信息</returns>
        [HttpGet]
        [AllowAnonymous]
        [Route("ExistTenantName")]
        public ServiceResult<bool> ExistTenantName(string tenantName)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.ExistTenantName(tenantName);
                },
                Logger);
        }

        /// <summary>
        /// 根据租户代码获取租户信息
        /// </summary>
        /// <param name="tenantName">租户代码</param>
        /// <returns>租户信息</returns>
        [HttpGet]
        [Authorize]
        [Route("GetTenantByTenantName")]
        public async Task<ServiceResult<Tenant>> GetTenantByTenantName(string tenantName)
        {
            return await ServiceWrapper.InvokeAsync(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                async () =>
                {
                    return await TenantStore.GetTenantUserByNameAsync(tenantName);
                },
                Logger);
        }
        /// <summary>
        /// 根据租户代码或是租户昵称获取租户信息
        /// </summary>
        /// <param name="tenantName">租户代码或是租户昵称</param>
        /// <returns>租户信息</returns>
        [HttpGet]
        [Authorize]
        [Route("GetTenantByNameOrNickName")]
        public async Task<ServiceResult<Tenant>> GetTenantByNameOrNickName(string tenantName)
        {
            return await ServiceWrapper.InvokeAsync(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                async () =>
                {
                    return await TenantStore.GetTenantByNameOrNickNameAsync(tenantName);
                },
                Logger);
        }
        /// <summary>
        /// 根据租户独立域名获取租户信息
        /// </summary>
        /// <param name="domainName">租户独立域名</param>
        /// <returns>租户信息</returns>
        [HttpGet]
        [Authorize]
        [Route("GetTenantEndWithDomainName")]
        public async Task<ServiceResult<Tenant>> GetTenantEndWithDomainName(string domainName)
        {
            return await ServiceWrapper.InvokeAsync(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                async  () =>
                {
                    return await TenantStore.GetTenantEndWithDomainName(domainName);
                },
                Logger);
        }
        /// <summary>
        /// 根据租户代码获取租户详情信息
        /// </summary>
        /// <param name="tenantName">租户代码</param>
        /// <returns>租户详情信息</returns>
        [HttpGet]
        [Authorize]
        [Route("GetTenantUserByName")]
        public ServiceResult<TenantUserDTO> GetTenantUserByName(string tenantName)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetTenantUserByName(tenantName);
                },
                Logger);
        }

        /// <summary>
        /// 根据租户代码列表获取租户信息列表
        /// </summary>
        /// <param name="tenantNames">租户代码列表</param>
        /// <returns>租户信息列表</returns>
        [HttpPost]
        [Authorize]
        [Route("GetTenantByTenantNames")]
        public ServiceResult<List<Tenant>> GetTenantByTenantNames([FromBody]List<string> tenantNames)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetTenantsByNames(tenantNames).ToList();
                },
                Logger);
        }
        /// <summary>
        /// 根据开通应用Id及租户代码列表获取租户信息列表
        /// </summary>
        /// <param name="appId">开通的应用Id</param>
        /// <param name="tenantNames">租户代码列表</param>
        /// <returns>租户信息列表</returns>
        [HttpPost]
        [Authorize]
        [Route("GetOpenAppTenantsByNames")]
        public ServiceResult<List<Tenant>> GetOpenAppTenantsByNames(Guid appId, [FromBody]List<string> tenantNames)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetOpenAppTenantsByNames(appId, tenantNames);
                },
                Logger);
        }
        /// <summary>
        /// 根据开通应用Id获取租户信息列表
        /// </summary>
        /// <param name="appId">开通的应用Id</param>
        /// <returns>租户信息列表</returns>
        [HttpGet]
        [Authorize]
        [Route("GetAllOpenAppTenants")]
        public ServiceResult<List<Tenant>> GetAllOpenAppTenants(Guid appId)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetAllOpenAppTenants(appId);
                },
                Logger);
        }

        /// <summary>
        /// 根据条件，获取租户分页数据
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">页面记录数</param>
        /// <param name="applicationId">开通应用Id</param>
        /// <param name="tenantDisplayName">租户中文名</param>
        /// <param name="exceptTenant">所需排除的租户代码</param>
        /// <returns>租户信息列表</returns>
        [HttpGet]
        [Authorize]
        [Route("GetTenantUsersByOpenAppId")]
        public ServiceResult<PaginatedBaseDTO<TenantSimpleDTO>> GetTenantUsersByOpenAppId(
            int pageIndex, int pageSize,
            Guid applicationId, string tenantDisplayName, string exceptTenant)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    var exceptTenants = !string.IsNullOrWhiteSpace(exceptTenant)
                        ? new List<string>() { exceptTenant, TenantConstant.DbaTenantName }
                        : new List<string>() { TenantConstant.DbaTenantName };
                    return TenantStore.GetTenantUsersByOpenAppId(pageIndex, pageSize, applicationId, tenantDisplayName,
                        exceptTenants, false);
                },
                Logger);
        }
        /// <summary>
        /// 根据条件，获取租户分页数据
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">页面记录数</param>
        /// <param name="tenantName">租户代码</param>
        /// <param name="tenantDisplayName">租户中文名</param>
        /// <param name="execptTenants">所需排除的租户代码列表</param>
        /// <returns>租户信息列表</returns>
        [HttpPost]
        [Authorize]
        [Route("GetTenantUsersByPredicate")]
        public ServiceResult<PaginatedBaseDTO<TenantSimpleDTO>> GetTenantUsersByPredicate(
            int pageIndex, int pageSize, string tenantName, string tenantDisplayName,
            [FromBody]List<string> execptTenants)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetTenantUsersByPredicate(pageIndex, pageSize, execptTenants, tenantName, tenantDisplayName);
                },
                Logger);
        }
        /// <summary>
        /// 根据条件，获取租户分页数据
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">页面记录数</param>
        /// <param name="tenantDisplayName">租户中文名</param>
        /// <param name="providerTenantName">提供金融服务的租户代码</param>
        /// <param name="tally">租户类型，可为空</param>
        /// <returns>租户信息列表</returns>
        [HttpGet]
        [Authorize]
        [Route("GetTenantUsers")]
        public ServiceResult<PaginatedBaseDTO<TenantSimpleDTO>> GetTenantUsers(
            int pageIndex, int pageSize, string tenantDisplayName,
            string providerTenantName = null, TenantType? tally = null)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetTenantUsers(pageIndex, pageSize, tenantDisplayName, providerTenantName, tally);
                },
                Logger);
        }

        /// <summary>
        /// 租户模糊查询
        /// </summary>
        /// <param name="key">租户代码的模糊Key</param>
        /// <returns>租户名称及代码的KeyValue值</returns>
        [HttpGet]
        [AllowAnonymous]
        [Route("QueryTenantByKey")]
        public ServiceResult<List<JsonDictionaryDTO>> QueryTenantByKey(string key)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.QueryTenantByKey(key);
                },
                Logger);
        }

        /// <summary>
        /// 查询租户的显示名称
        /// </summary>
        /// <param name="tenantName">租户代码</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        [Route("GetTenantDisplayNameByName")]
        public ServiceResult<string> GetTenantDisplayNameByName(string tenantName)
        {
            return ServiceWrapper.Invoke(
                ServiceName,
                MethodBase.GetCurrentMethod().Name,
                () =>
                {
                    return TenantStore.GetTenantDisplayNameByName(tenantName);
                },
                Logger);
        }

        #region Cache
        [HttpGet]
        [AllowAnonymous]
        [Route("ClearAllCache")]
        public JsonResult ClearAllCache()
        {
            Service.Core.CacheUtil.RemoveAllCache();

            return new JsonResult(new { success = true, message = "清除缓存成功" });
        }
        [HttpGet]
        [AllowAnonymous]
        [Route("RemoveCacheByKey")]
        public JsonResult RemoveCacheByKey(string key)
        {
            Service.Core.CacheUtil.RemoveCache(key);

            return new JsonResult(new { success = true, message = "清除缓存成功" });
        }

        #endregion

        [HttpGet]
        [AllowAnonymous]
        [Route("DownLoadLogFile")]
        public ActionResult DownLoadLogFile(string name)
        {
            var url = ServerPath + "/logs/" + name + ".log";
            return File(url, "text/plain");
        }

        #region 文件地址
        private string _serverPath;
        protected string ServerPath
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_tempDir))
                {
                    var env = (Microsoft.AspNetCore.Hosting.IHostingEnvironment)
                        HttpContext.RequestServices.GetService(
                            typeof(Microsoft.AspNetCore.Hosting.IHostingEnvironment));
                    _serverPath = env.ContentRootPath;
                }
                return _serverPath;
            }
            set { _serverPath = value; }
        }

        private string _tempDir;
        //上传使用
        protected string TempDir
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_tempDir))
                {
                    _tempDir = ServerPath + "/TempDir";
                    if (!Directory.Exists(_tempDir))
                    {
                        try
                        {
                            Directory.CreateDirectory(_tempDir);
                        }
                        catch (SecurityException)
                        {

                        }
                    }
                }
                return _tempDir;
            }
            set { _tempDir = value; }
        }
        #endregion
    }
}
